package eos.dom.server;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import javax.servlet.ServletException;
import javax.servlet.http.*;

import org.jdom.output.XMLOutputter;


@SuppressWarnings("serial")
public class DominionAppServerServlet extends HttpServlet {

	HttpURLConnection server;

	public void doGet(HttpServletRequest req, HttpServletResponse resp)
	throws IOException {
		PersistenceManager pmf = PMF.get().getPersistenceManager();
		String query = "select from " + Game.class.getName();
		List<Game> games = (List<Game>) pmf.newQuery(query).execute();
		org.jdom.Document doc =getUpdate("eos", "eos", resp);
		XMLOutputter output = new XMLOutputter();
		output.output(doc,System.out);
		resp.getWriter().flush();
		pmf.close();
	}


	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
	throws ServletException, IOException {
		String command = req.getParameter("command");
		String name = req.getParameter("name");
		if(command != null){	
			if(command.equals("CREATE_GAME")){
				//Create a new game
				createGame(name,resp,req);
			}else if(command.equals("JOIN_GAME")){
				//Join a game
				String host = req.getParameter("host");
				joinGame(name,host,resp,req);
			}else if(command.equals("GET_GAME_LIST")){
				//Get game list
				generateGameList(resp);
			}else if(command.equals("GET_UPDATE")){
				String host = req.getParameter("host");
				getUpdate(host,name,resp);
			}else if(command.equals("PREPARE_GAME")){
				System.out.println(req);
				int nbCards = Integer.parseInt(req.getParameter("nbCards"));
				int[] cardsChosen = new int[nbCards];
				for(int i = 0;i<nbCards;i++){
					cardsChosen[i] = Integer.parseInt(req.getParameter("card"+i));
				}
				prepareGame(cardsChosen,name);
			}else if(command.equals("END_TURN")){
				//End current player turn
				endTurn(name);
			}else if(command.equals("END_GAME")){
				//End and delete game created by host
				endGame(name);
			}
		}
	}


	private void prepareGame(int[] cardsChosen, String host) {
		PersistenceManager pmf = PMF.get().getPersistenceManager();

		Game game = getGame(host,pmf);
		for(int c:cardsChosen){
			System.out.println(c);
		}
		game.prepareCards(cardsChosen);
		Transaction tx = pmf.currentTransaction();
		try{
			tx.begin();
			pmf.makePersistent(game);
			tx.commit();
		}finally{
			if (tx.isActive()) {
	            tx.rollback();
	        }
		}
		pmf.close();
		
	}


	private org.jdom.Document getUpdate(String host, String name, HttpServletResponse resp) throws IOException {
		//generate XML file
		PersistenceManager pmf = PMF.get().getPersistenceManager();
		
		Game game = getGame(host,pmf);
		org.jdom.Document gameInfo = game.generateGameData(name);
		pmf.close();
		
		XMLOutputter output = new XMLOutputter();
		output.output(gameInfo,resp.getWriter());
		resp.getWriter().flush();
		
		return gameInfo;
	}



	private void endGame(String name) {
		PersistenceManager pmf = PMF.get().getPersistenceManager();

		String query = "select from " + Game.class.getName();
		List<Game> games = (List<Game>) pmf.newQuery(query).execute();
		for(Game g:games){
			if(g.getHost().equals(name)){
				pmf.deletePersistent(g);
			}
		}
		pmf.close();
	}


	private void endTurn(String name) {
		// TODO Auto-generated method stub

	}


	private void generateGameList(HttpServletResponse resp) throws IOException {
		PersistenceManager pmf = PMF.get().getPersistenceManager();

		String query = "select from " + Game.class.getName();
		List<Game> games = (List<Game>) pmf.newQuery(query).execute();
		for(Game g:games){
			System.out.println(g);
			resp.getWriter().println(g);
		}
		pmf.close();
	}


	private void joinGame(String name, String host, HttpServletResponse resp, HttpServletRequest req) throws IOException {

		PersistenceManager pmf = PMF.get().getPersistenceManager();

		String query = "select from " + Game.class.getName();
		List<Game> games = (List<Game>) pmf.newQuery(query).execute();
		Game gameToJoin = null;
		for(Game g:games){
			if(g.getHost().equals(host)){
				gameToJoin = g;
			}
		}
		if(gameToJoin==null){
			resp.getWriter().println("NOT_VALID_HOST");
		}else{
			if(gameToJoin.addNewPlayer(name)){
			resp.getWriter().println("OK");
			}else{
				resp.getWriter().println("PLAYER_ALREADY_HERE");
			}
			pmf.makePersistent(gameToJoin);
		}
			resp.getWriter().flush();
		pmf.close();

	}


	private void createGame(String name, HttpServletResponse resp, HttpServletRequest req) throws IOException {
		Game game = new Game(name);
		System.out.println(game.getPlayers().get(0).moreInfo());
		PersistenceManager pmf = PMF.get().getPersistenceManager();
		Transaction tx = pmf.currentTransaction();
		try{
			tx.begin();
			pmf.makePersistent(game);
			tx.commit();
		}finally{
			if (tx.isActive()) {
	            tx.rollback();
	        }
		}
		pmf.close();
		resp.getWriter().println("OK");
	}

	private Game getGame(String host,PersistenceManager pmf) {
		String query = "select from " + Game.class.getName();
		List<Game> games = (List<Game>) pmf.newQuery(query).execute();
		for(Game g:games){
			System.out.println("HOST"+g.getHost());
			if(g.getHost().equals(host)){
				return g;
			}
		}
		return null;
	}

	/**
	 * @param method: String object for client method (POST, GET,...)
	 */
	public void connect(String method,String ip) throws Exception
	{
		try
		{
			URL u = new URL(ip);
			server = (HttpURLConnection)u.openConnection();
			server.setDoInput(true);
			server.setDoOutput(true);
			server.setRequestMethod(method);
			server.connect();
		}
		catch (Exception e)
		{
			throw new Exception("Connection failed\n"+e.getMessage()+"\n"+server.getURL().toString());
		}
	}

	public void disconnect()
	{
		server.disconnect();
	}

}
